package me.bincker.formwork.web.modules.system.controller

import me.bincker.formwork.web.core.annotation.Permission
import me.bincker.formwork.web.core.exception.NotFoundException
import me.bincker.formwork.web.core.validated.ValidAdd
import me.bincker.formwork.web.modules.system.entity.User
import me.bincker.formwork.web.modules.system.form.UserForm
import me.bincker.formwork.web.modules.system.service.IUserService
import org.springframework.data.domain.Example
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("users")
class UserController(
        val userService: IUserService,
        val passwordEncoder: PasswordEncoder
){
    @GetMapping
    @Permission("用户列表", "user.page")
    fun getPage(pageable: Pageable, user: User?): Page<User> {
        return if(user == null){
            userService.findAll(pageable)
        }else{
            userService.findAll(Example.of(user), pageable)
        }
    }

    @GetMapping("{id}")
    @Permission("用户详情", "user.detail")
    fun getOne(@PathVariable id: String) = userService.getOne(id)

    @PostMapping
    @Permission("添加用户", "user.add")
    fun add(@RequestBody@Validated(ValidAdd::class) userForm: UserForm) : User {
        val user = User()
        user.username = userForm.username
        user.nickname = userForm.nickname ?: userForm.username
        user.encodedPassword = passwordEncoder.encode(userForm.password)
        user.gender = userForm.gender
        user.email = userForm.email
        user.phoneNumber = userForm.phoneNumber
        user.locked = false
        user.roleList = userForm.roleList
        return userService.save(user)
    }

    @PutMapping
    @Permission("修改用户", "user.edit")
    fun put(@RequestBody@Validated user: User): User{
        val target = userService.getOne(user.id)
        target.username = user.username
        target.nickname = user.nickname
        target.gender = user.gender
        target.email = user.email
        target.phoneNumber = user.phoneNumber
        target.locked = user.locked
        target.roleList = user.roleList
        return userService.save(target)
    }

    @PatchMapping("{id}/change-password")
    @Permission("修改密码", "user.change-password")
    fun changePassword(@PathVariable id: String, password: String): User{
        val target = userService.findById(id) ?: throw NotFoundException()
        target.encodedPassword = passwordEncoder.encode(password)
        return userService.save(target)
    }
}
